/**公众号buyer login相关**/

package oauth

import (
	"encoding/json"
	"errors"
	"fmt"
	//"github.com/astaxie/beego"
	"wxsdk/miniapp/core"
)

const (
	assistAccessTokenURL  = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s&component_access_token=%s"
	assistRefreshTokenURL = "https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=%s&grant_type=refresh_token&component_appid=%s&component_access_token=%s&refresh_token=%s"
	accessTokenURL        = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
	userInfoURL           = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"
	userInfoURL2          = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN"
)

// 第三方平台代替公众号实现登录(代管登陆)
type PubCode2SessionResult struct {
	*core.ErrorResponse
	*PubCode2SessionRsp
}
type PubCode2SessionRsp struct {
	Openid       string `json:"openid"`        //授权用户唯一标识
	AccessToken  string `json:"access_token"`  //买家接口调用凭证,和商家access_token区分开
	RefreshToken string `json:"refresh_token"` //用户刷新access_token
	Scope        string `json:"scope"`         //用户授权的作用域，使用逗号（,）分隔
	ExpiresIn    int64  `json:"expires_in"`    //access_token接口调用凭证超时时间，单位（秒）
}

func AssistPubCode2Session(appId, isvAppId, isvAccessToken, code string) (string, string, error) {
	client := core.GetPostJSONClient()
	var rsp PubCode2SessionResult
	serverUrl := fmt.Sprintf(assistAccessTokenURL, appId, code, isvAppId, isvAccessToken)
	tbdata, err := client.Excute("POST", serverUrl, nil, &rsp)
	if err != nil {
		//beego.Critical(err.Error())
		return "", "", err
	}
	if rsp.ErrorResponse != nil {
		//beego.Critical("error:", string(tbdata))
		return "", "", errors.New(string(tbdata))
	}
	return rsp.PubCode2SessionRsp.Openid, rsp.PubCode2SessionRsp.AccessToken, nil
}

func AssistPubRefreshToken2Session(appId, isvAppId, isvToken, refreshToken string) (string, string, error) {
	client := core.GetPostJSONClient()
	var rsp PubCode2SessionResult
	serverUrl := fmt.Sprintf(assistRefreshTokenURL, appId, isvAppId, isvToken, refreshToken)
	tbdata, err := client.Excute("POST", serverUrl, nil, &rsp)
	if err != nil {
		//beego.Critical(err.Error())
		return "", "", err
	}
	if rsp.ErrorResponse != nil {
		//beego.Critical("error:", string(tbdata))
		return "", "", errors.New(string(tbdata))
	}
	return rsp.PubCode2SessionRsp.Openid, rsp.PubCode2SessionRsp.AccessToken, nil
}

/*********************自管公众号实现登录******************************/

// GetUserAccessToken 通过网页授权的code 换取access_token(区别于context中的access_token)
func PubCode2Session(appId, appSecret, code string) (result PubCode2SessionResult, err error) {
	urlStr := fmt.Sprintf(accessTokenURL, appId, appSecret, code)
	var body []byte
	body, err = core.GetCommonFileByHttp(urlStr)
	if err != nil {
		return
	}
	err = json.Unmarshal(body, &result)
	if err != nil {
		return
	}
	if result.ErrorResponse != nil {
		//beego.Critical("error:", result.ErrorResponse.ErrCode, result.ErrorResponse.ErrMsg)
		err = errors.New(result.ErrorResponse.ErrMsg)
		return
	}
	return
}

/****************共用API**************************/
type WaterMark struct {
	AppID     string `json:"appid"`
	Timestamp int    `json:"timestamp"`
}

type BuyerUserInfo struct {
	*core.ErrorResponse
	OpenID     string `json:"openid"`                //app,pub
	Nickname   string `json:"nickname"`              //app,pub
	Gender     int    `json:"gender,omitempty"`      //app
	Language   string `json:"language,omitempty"`    //app,pub
	Country    string `json:"country"`               //app,pub
	Province   string `json:"province"`              //app,pub
	City       string `json:"city"`                  //app,pub
	AvatarURL  string `json:"avatarUrl,omitempty"`   //app
	Unionid    string `json:"unionid,omitempty"`     //app,pub
	SessionKey string `json:"session_key,omitempty"` //app
	WaterMark  `json:"watermark,omitempty"`          //app
	//
	Sex            int      `json:"sex,omitempty"`             //pub
	Headimgurl     string   `json:"headimgurl,omitempty"`      //pub
	Privilege      []string `json:"privilege,omitempty"`       //pub
	Subscribe      int      `json:"subscribe,omitempty"`       //pub
	SubscribeTime  int64    `json:"subscribe_time,omitempty"`  //pub
	Groupid        int      `json:"groupid,omitempty"`         //pub
	TagidList      []int    `json:"tagid_list,omitempty"`      //pub
	SubscribeScene string   `json:"subscribe_scene,omitempty"` //pub
	Remark         string   `json:"remark,omitempty"`          //pub
	QrScene        int      `json:"qr_scene,omitempty"`        //pub
	QrSceneStr     string   `json:"qr_scene_str,omitempty"`    //pub
}

//此处是顾客的session_key
func GetUserInfo(accessToken, openID string) (result BuyerUserInfo, err error) {
	urlStr := fmt.Sprintf(userInfoURL, accessToken, openID)
	var body []byte
	body, err = core.GetCommonFileByHttp(urlStr)
	if err != nil {
		return
	}
	//beego.Debug("GetUserInfo", string(body))
	err = json.Unmarshal(body, &result)
	if err != nil {
		return
	}
	if result.ErrorResponse != nil {
		//beego.Critical("error:", result.ErrorResponse.ErrCode, result.ErrorResponse.ErrMsg)
		err = errors.New(result.ErrorResponse.ErrMsg)
		return
	}
	return
}

//获取用户基本信息(UnionID机制),此处是商家的token!
func GetUserInfo2(accessToken, openID string) (rslt *BuyerUserInfo, err error) {
	urlStr := fmt.Sprintf(userInfoURL2, accessToken, openID)
	var body []byte
	var result struct {
		core.Error
		BuyerUserInfo
	}
	body, err = core.GetCommonFileByHttp(urlStr)
	if err != nil {
		return
	}
	//beego.Debug("GetUserInfo2", string(body))
	err = json.Unmarshal(body, &result)
	if err != nil {
		return
	}
	if result.ErrCode != core.ErrCodeOK {
		err = &result.Error
		return
	}
	rslt = &result.BuyerUserInfo
	return
}
